package com.zhang.runner;

import cn.hutool.core.util.RandomUtil;
import com.zhang.constants.PermissionConstant;
import com.zhang.modules.api.entity.Api;
import com.zhang.modules.api.service.IApiService;
import com.zhang.modules.auth.eneity.Permission;
import com.zhang.modules.auth.eneity.Role;
import com.zhang.modules.auth.rep.PermissionRep;
import com.zhang.modules.auth.rep.RolePermissionRep;
import com.zhang.modules.auth.service.IPermissionService;
import com.zhang.modules.auth.service.IRoleService;
import com.zhang.modules.user.entity.SysUser;
import com.zhang.modules.user.service.ISysUserService;
import com.zhang.modules.user.service.PasswordEncoder;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.*;

@Order(Ordered.HIGHEST_PRECEDENCE)
@Component
public class PrevInitRunner implements ApplicationRunner ,Ordered{

    private IPermissionService permissionService;
    private IRoleService roleService;

    private IApiService apiService;

    private ISysUserService userService;


    private final PermissionRep permissionRep;
    private final RolePermissionRep rolePermissionRep;

    public PrevInitRunner(IPermissionService permissionService, IRoleService roleService, IApiService apiService, ISysUserService userService,
                          PermissionRep permissionRep,
                          RolePermissionRep rolePermissionRep) {
        this.permissionService = permissionService;
        this.roleService = roleService;
        this.apiService = apiService;
        this.userService = userService;
        this.permissionRep = permissionRep;
        this.rolePermissionRep = rolePermissionRep;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        List<Permission> permissions = this.collectingPermission();
        Role adminRole = setAdminRole(permissions);
        setAdminUser(adminRole);
    }



    /**
     * 收集Api权限和Menu权限到权限表
     */
    public List<Permission> collectingPermission(){
        //清空权限表
        permissionService.cleanUp();

        List<Permission> prevs = new ArrayList<>();

        //获取全部的api 收集全部的api信息到权限表
        List<Api> apis = apiService.findApi();
        apis.forEach(api ->{
            Permission permission = new Permission();
            permission.setType(PermissionConstant.PERV_TYPE_API);
            BeanUtils.copyProperties(api,permission);

            prevs.add(permission);
        });



        //保存所有权限
        return permissionService.saveAll(prevs);


    }

    /**
     * 设置admin角色拥有权限表中的所有权限
     */
    public Role setAdminRole(List<Permission> permissions){
        Role role = roleService.get(PermissionConstant.ROLE_ADMIN_ID);
        if (role == null){
            Role localRole = new Role();
            localRole.setId(PermissionConstant.ROLE_ADMIN_ID);
            localRole.setCode(PermissionConstant.ROLE_ADMIN_CODE);
            localRole.setName(PermissionConstant.ROLE_ADMIN_NAME);
            localRole.setStatus(PermissionConstant.ROLE_STATUS_ENABLE);
            role = roleService.save(localRole);
        }

        //删除已经不存在的权限
        Set<String> ids = new HashSet<>();
        permissions.forEach(item ->ids.add(item.getId()));
        roleService.deleteByIdNotIn(ids);


        //保存角色<--->权限关系
        role.setPermissions(new HashSet<>(permissions));
        roleService.save(role);

        return role;
    }

    /**
     * @param adminRole
     * 生成admin用户，并把admin角色赋给自己
     */
    private void setAdminUser(Role adminRole) {
        SysUser Admin = userService.get("1");
        if (Admin == null){
            //创建admin用户
            SysUser admin = new SysUser();
            admin.setId("1");
            admin.setUserAccount("admin");
            admin.setNickName("管理员1号");
            admin.setPassword("123456");
            admin.setRoles(new HashSet<>(Arrays.asList(adminRole)));
            userService.save(admin);
        }
    }

    @Override
    public int getOrder() {
        return 10;
    }
}
